home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / disk / misc / ADFlib.lha / Lib / adf_file.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  20KB  |  728 lines

  1. /*
  2.  *  ADF Library. (C) 1997-1998 Laurent Clevy
  3.  *
  4.  *  adf_file.c
  5.  *
  6.  *  file code
  7.  */
  8.  
  9. #include<stdlib.h>
  10. #include<string.h>
  11.  
  12. #include"adf_util.h"
  13. #include"adf_file.h"
  14. #include"adf_str.h"
  15. #include"defendian.h"
  16. #include"adf_raw.h"
  17. #include"adf_disk.h"
  18. #include"adf_dir.h"
  19. #include"adf_bitm.h"
  20. #include"adf_cache.h"
  21.  
  22. extern struct Env adfEnv;
  23.  
  24. void adfFileTruncate(struct Volume *vol, SECTNUM nParent, char *name)
  25. {
  26.  
  27. }
  28.  
  29.  
  30. /*
  31.  * adfFileFlush
  32.  *
  33.  */
  34. void adfFlushFile(struct File *file)
  35. {
  36.     struct bEntryBlock parent;
  37.     struct bOFSDataBlock *data;
  38.  
  39.     if (file->currentExt) {
  40.         if (file->writeMode)
  41.             adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
  42.                 file->currentExt);
  43.     }
  44.     if (file->currentData) {
  45.         if (file->writeMode) {
  46.             file->fileHdr->byteSize = file->pos;
  47.             if (isOFS(file->volume->dosType)) {
  48.                 data = (struct bOFSDataBlock *)file->currentData;
  49.                 data->dataSize = file->posInDataBlk;
  50.             }
  51.             if (file->fileHdr->byteSize>0)
  52.                 adfWriteDataBlock(file->volume, file->curDataPtr, 
  53.                     file->currentData);
  54.         }
  55.     }
  56.     if (file->writeMode) {
  57.         file->fileHdr->byteSize = file->pos;
  58. //printf("pos=%ld\n",file->pos);
  59.         adfTime2AmigaTime(adfGiveCurrentTime(),
  60.             &(file->fileHdr->days),&(file->fileHdr->mins),&(file->fileHdr->ticks) );
  61.         adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr);
  62.  
  63.         if (isDIRCACHE(file->volume->dosType)) {
  64. //printf("parent=%ld\n",file->fileHdr->parent);
  65.             adfReadEntryBlock(file->volume, file->fileHdr->parent, &parent);
  66.             adfUpdateCache(file->volume, &parent, (struct bEntryBlock*)file->fileHdr,FALSE);
  67.         }
  68.         adfUpdateBitmap(file->volume);
  69.     }
  70. }
  71.  
  72.  
  73.  
  74. /*
  75.  * adfFreeFileBlocks
  76.  *
  77.  */
  78. RETCODE adfFreeFileBlocks(struct Volume* vol, struct bFileHeaderBlock *entry)
  79. {
  80.     long n;    
  81.     SECTNUM *sectTab;
  82.     long nbSect, datSect, extSect;
  83.     int i;
  84.     SECTNUM nSect;
  85.     struct bFileExtBlock extBlock;
  86.     RETCODE rc = RC_OK;
  87.  
  88.     nbSect = adfFileRealSize( entry->byteSize, vol->datablockSize, &datSect, 
  89.         &extSect);
  90.     sectTab=(SECTNUM*)malloc(nbSect*sizeof(SECTNUM));
  91.     if (!sectTab) {
  92.         (*adfEnv.eFct)("adfFreeFileBlocks : malloc");
  93.     }
  94. /*printf("data=%d ext=%d\n",datSect,extSect);*/
  95.     n=0;    
  96.     /* in file header block */
  97.     sectTab[n++] = entry->headerKey;
  98.     for(i=0; i<entry->highSeq; i++)
  99.         sectTab[n++] = entry->dataBlocks[MAX_DATABLK-1-i];
  100.  
  101.     /* in file extension blocks */
  102.     nSect = entry->extension;
  103.     while(nSect!=0) {
  104.         sectTab[n++] = nSect;
  105.         adfReadFileExtBlock(vol, nSect, &extBlock);
  106.         for(i=0; i<extBlock.highSeq; i++)
  107.             sectTab[n++] = extBlock.dataBlocks[MAX_DATABLK-1-i];
  108.         nSect = extBlock.extension;
  109.     }
  110.     if (nbSect!=n)
  111.         (*adfEnv.wFct)("adfFreeFileBlocks : less blocks than expected");
  112.  
  113.     for(i=0; i<nbSect; i++) {
  114.         adfSetBlockFree(vol, sectTab[i]);
  115. /*printf("sect=%d ",sectTab[i]);*/
  116.     }
  117.  
  118.     free(sectTab);
  119.     
  120.     return rc;
  121. }
  122.  
  123.  
  124. /*
  125.  * adfFileRealSize
  126.  *
  127.  * Compute and return real number of block used by one file
  128.  * Compute number of datablocks and file extension blocks
  129.  *
  130.  */
  131. long adfFileRealSize(unsigned long size, int blockSize, long *dataN, long *extN)
  132. {
  133.     long data, ext;
  134.  
  135.    /*--- number of data blocks ---*/
  136.     data = size / blockSize;
  137.     if ( size % blockSize )
  138.         data++;
  139.  
  140.     /*--- number of header extension blocks ---*/
  141.     ext = 0;
  142.     if (data>MAX_DATABLK) {
  143.         ext = (data-MAX_DATABLK) / MAX_DATABLK;
  144.         if ( (data-MAX_DATABLK) % MAX_DATABLK )
  145.             ext++;
  146.     }
  147.  
  148.     if (dataN)
  149.         *dataN = data;
  150.     if (extN)
  151.         *extN = ext;
  152.         
  153.     return(ext+data+1);
  154. }
  155.  
  156.  
  157. /*
  158.  * adfWriteFileHdrBlock
  159.  *
  160.  */
  161. RETCODE adfWriteFileHdrBlock(struct Volume *vol, SECTNUM nSect, struct bFileHeaderBlock* fhdr)
  162. {
  163.     unsigned char buf[512];
  164.     unsigned long newSum;
  165.     RETCODE rc = RC_OK;
  166. //printf("adfWriteFileHdrBlock %ld\n",nSect);
  167.     fhdr->type = T_HEADER;
  168.     fhdr->dataSize = 0;
  169.     fhdr->secType = ST_FILE;
  170.  
  171.     memcpy(buf, fhdr, sizeof(struct bFileHeaderBlock));
  172. #ifdef LITT_ENDIAN
  173.     swapEndian(buf, SWBL_FILE);
  174. #endif
  175.     newSum = adfNormalSum(buf,20,sizeof(struct bFileHeaderBlock));
  176.     swLong(buf+20, newSum);
  177. //    *(unsigned long*)(buf+20) = swapLong((unsigned char*)&newSum);
  178.  
  179.     adfWriteBlock(vol, nSect, buf);
  180.  
  181.     return rc;
  182. }
  183.  
  184.  
  185. /*
  186.  * adfFileSeek
  187.  *
  188.  */
  189. void adfFileSeek(struct File *file, unsigned long pos)
  190. {
  191.     SECTNUM extBlock, nSect;
  192.     unsigned long nPos;
  193.     int i;
  194.     
  195.     nPos = min(pos, file->fileHdr->byteSize);
  196.     file->pos = nPos;
  197.     extBlock = adfPos2DataBlock(nPos, file->volume->datablockSize,
  198.         &(file->posInExtBlk), &(file->posInDataBlk), &(file->curDataPtr) );
  199.     if (extBlock==-1) {
  200.         adfReadDataBlock(file->volume,
  201.             file->fileHdr->dataBlocks[MAX_DATABLK-1-file->curDataPtr],
  202.             file->currentData);
  203.     }
  204.     else {
  205.         nSect = file->fileHdr->extension;
  206.         i = 0;
  207.         while( i<extBlock && nSect!=0 ) {
  208.             adfReadFileExtBlock(file->volume, nSect, file->currentExt );
  209.             nSect = file->currentExt->extension;
  210.         }
  211.         if (i!=extBlock)
  212.             (*adfEnv.wFct)("error");
  213.         adfReadDataBlock(file->volume,
  214.             file->currentExt->dataBlocks[file->posInExtBlk], file->currentData);
  215.     }
  216. }
  217.  
  218.  
  219. /*
  220.  * adfFileOpen
  221.  *
  222.  */ 
  223. struct File* adfOpenFile(struct Volume *vol, char* name, char *mode)
  224. {
  225.     struct File *file;
  226.     SECTNUM nSect;
  227.     struct bEntryBlock entry, parent;
  228.     BOOL write;
  229.  
  230.     write=( strcmp("w",mode)==0 || strcmp("a",mode)==0 );
  231.     
  232.     if (write && vol->dev->readOnly) {
  233.         (*adfEnv.wFct)("adfFileOpen : device is mounted 'read only'");
  234.         return NULL;
  235.     }
  236.  
  237.     adfReadEntryBlock(vol, vol->curDirPtr, &parent);
  238.  
  239.     nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, NULL);
  240.     if (!write && nSect==-1) {
  241.         (*adfEnv.wFct)("adfFileOpen : file not found"); return NULL; }
  242.     if (!write && hasR(entry.access)) {
  243.         (*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }
  244. /*    if (entry.secType!=ST_FILE) {
  245.         (*adfEnv.wFct)("adfFileOpen : not a file"); return NULL; }
  246.     if (write && (hasE(entry.access)||hasW(entry.access))) {
  247.         (*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }  
  248. */    if (write && nSect!=-1) {
  249.         (*adfEnv.wFct)("adfFileOpen : file already exists"); return NULL; }  
  250.  
  251.     file = (struct File*)malloc(sizeof(struct File));
  252.     if (!file) { (*adfEnv.wFct)("adfFileOpen : malloc"); return NULL; }
  253.     file->fileHdr = (struct bFileHeaderBlock*)malloc(sizeof(struct bFileHeaderBlock));
  254.     if (!file->fileHdr) {
  255.         (*adfEnv.wFct)("adfFileOpen : malloc"); 
  256.         free(file); return NULL; 
  257.     }
  258.     file->currentData = malloc(512*sizeof(unsigned char));
  259.     if (!file->currentData) { 
  260.         (*adfEnv.wFct)("adfFileOpen : malloc"); 
  261.         free(file->fileHdr); free(file); return NULL; 
  262.     }
  263.  
  264.     file->volume = vol;
  265.     file->pos = 0;
  266.     file->posInExtBlk = 0;
  267.     file->posInDataBlk = 0;
  268.     file->writeMode = write;
  269.     file->currentExt = NULL;
  270.     file->nDataBlock = 0;
  271.  
  272.     if (strcmp("w",mode)==0) {
  273.         memset(file->fileHdr,0,512);
  274.         adfCreateFile(vol,vol->curDirPtr,name,file->fileHdr);
  275.         file->eof = TRUE;
  276.     }
  277.     else if (strcmp("a",mode)==0) {
  278.         memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
  279.         file->eof = TRUE;
  280.         adfFileSeek(file, file->fileHdr->byteSize);
  281.     }
  282.     else if (strcmp("r",mode)==0) {
  283.         memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
  284.         file->eof = FALSE;
  285.     }
  286.  
  287. //puts("adfOpenFile");
  288.     return(file);
  289. }
  290.  
  291.  
  292. /*
  293.  * adfCloseFile
  294.  *
  295.  */
  296. void adfCloseFile(struct File *file)
  297. {
  298.  
  299.     if (file==0)
  300.         return;
  301. //puts("adfCloseFile in");
  302.  
  303.     adfFlushFile(file);
  304.  
  305.     if (file->currentExt)
  306.         free(file->currentExt);
  307.     
  308.     if (file->currentData)
  309.         free(file->currentData);
  310.     
  311.     free(file->fileHdr);
  312.     free(file);
  313.  
  314. //puts("adfCloseFile out");
  315. }
  316.  
  317.  
  318. /*
  319.  * adfReadFile
  320.  *
  321.  */
  322. long adfReadFile(struct File* file, long n, unsigned char *buffer)
  323. {
  324.     long bytesRead;
  325.     unsigned char *dataPtr, *bufPtr;
  326.     int blockSize, size;
  327.  
  328.     if (n==0) return(n);
  329.     blockSize = file->volume->datablockSize;
  330. /*puts("adfReadFile");*/
  331.     if (file->pos+n > file->fileHdr->byteSize)
  332.         n = file->fileHdr->byteSize - file->pos;
  333.  
  334.     if (isOFS(file->volume->dosType))
  335.         dataPtr = (unsigned char*)(file->currentData)+24;
  336.     else
  337.         dataPtr = file->currentData;
  338.  
  339.     if (file->pos==0 || file->posInDataBlk==blockSize) {
  340.         adfReadNextFileBlock(file);
  341.         file->posInDataBlk = 0;
  342.     }
  343.  
  344.     bytesRead = 0; bufPtr = buffer;
  345.     size = 0;
  346.     while ( bytesRead < n ) {
  347.         size = min(n-bytesRead, blockSize-file->posInDataBlk);
  348.         memcpy(bufPtr, dataPtr+file->posInDataBlk, size);
  349.         bufPtr += size;
  350.         file->pos += size;
  351.         bytesRead += size;
  352.         file->posInDataBlk += size;
  353.         if (file->posInDataBlk==blockSize && bytesRead<n) {
  354.             adfReadNextFileBlock(file);
  355.             file->posInDataBlk = 0;
  356.         }
  357.     }
  358.     file->eof = (file->pos==file->fileHdr->byteSize);
  359.     return( bytesRead );
  360. }
  361.  
  362.  
  363. /*
  364.  * adfEndOfFile
  365.  *
  366.  */
  367. BOOL adfEndOfFile(struct File* file)
  368. {
  369.     return(file->eof);
  370. }
  371.  
  372.  
  373. /*
  374.  * adfReadNextFileBlock
  375.  *
  376.  */
  377. RETCODE adfReadNextFileBlock(struct File* file)
  378. {
  379.     SECTNUM nSect;
  380.     struct bOFSDataBlock *data;
  381.     RETCODE rc = RC_OK;
  382.  
  383.     data =(struct bOFSDataBlock *) file->currentData;
  384.  
  385.     if (file->nDataBlock==0) {
  386.         nSect = file->fileHdr->firstData;
  387.     }
  388.     else if (isOFS(file->volume->dosType)) {
  389.         nSect = data->nextData;
  390.     }
  391.     else {
  392.         if (file->nDataBlock<MAX_DATABLK)
  393.             nSect = file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock];
  394.         else {
  395.             if (file->nDataBlock==MAX_DATABLK) {
  396.                 file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
  397.                 if (!file->currentExt) (*adfEnv.eFct)("adfReadNextFileBlock : malloc");
  398.                 adfReadFileExtBlock(file->volume, file->fileHdr->extension,
  399.                     file->currentExt);
  400.                 file->posInExtBlk = 0;
  401.             }
  402.             else if (file->posInExtBlk==MAX_DATABLK) {
  403.                 adfReadFileExtBlock(file->volume, file->currentExt->extension,
  404.                     file->currentExt);
  405.                 file->posInExtBlk = 0;
  406.             }
  407.             nSect = file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk];
  408.             file->posInExtBlk++;
  409.         }
  410.     }
  411.     adfReadDataBlock(file->volume,nSect,file->currentData);
  412.  
  413.     if (isOFS(file->volume->dosType) && data->seqNum!=file->nDataBlock+1)
  414.         (*adfEnv.wFct)("adfReadNextFileBlock : seqnum incorrect");
  415.  
  416.     file->nDataBlock++;
  417.  
  418.     return rc;
  419. }
  420.  
  421.  
  422. /*
  423.  * adfWriteFile
  424.  *
  425.  */
  426. long adfWriteFile(struct File *file, long n, unsigned char *buffer)
  427. {
  428.     long bytesWritten;
  429.     unsigned char *dataPtr, *bufPtr;
  430.     int size, blockSize;
  431.     struct bOFSDataBlock *dataB;
  432.  
  433.     if (n==0) return (n);
  434. //puts("adfWriteFile");
  435.     blockSize = file->volume->datablockSize;
  436.     if (isOFS(file->volume->dosType)) {
  437.         dataB =(struct bOFSDataBlock *)file->currentData;
  438.         dataPtr = dataB->data;
  439.     }
  440.     else
  441.         dataPtr = file->currentData;
  442.  
  443.     if (file->pos==0 || file->posInDataBlk==blockSize) {
  444.         if (adfCreateNextFileBlock(file)==-1)
  445.             (*adfEnv.wFct)("adfWritefile : no more free sector availbale");                        
  446.         file->posInDataBlk = 0;
  447.     }
  448.  
  449.     bytesWritten = 0; bufPtr = buffer;
  450.     while( bytesWritten<n ) {
  451.         size = min(n-bytesWritten, blockSize-file->posInDataBlk);
  452.         memcpy(dataPtr+file->posInDataBlk, bufPtr, size);
  453.         bufPtr += size;
  454.         file->pos += size;
  455.         bytesWritten += size;
  456.         file->posInDataBlk += size;
  457.         if (file->posInDataBlk==blockSize && bytesWritten<n) {
  458.             if (adfCreateNextFileBlock(file)==-1)
  459.                 (*adfEnv.wFct)("adfWritefile : no more free sector availbale");                        
  460.             file->posInDataBlk = 0;
  461.         }
  462.     }
  463.     return( bytesWritten );
  464. }
  465.  
  466.  
  467. /*
  468.  * adfCreateNextFileBlock
  469.  *
  470.  */
  471. SECTNUM adfCreateNextFileBlock(struct File* file)
  472. {
  473.     SECTNUM nSect, extSect;
  474.     struct bOFSDataBlock *data;
  475.     unsigned int blockSize;
  476.     int i;
  477. //puts("adfCreateNextFileBlock");
  478.     blockSize = file->volume->datablockSize;
  479.     data = file->currentData;
  480.  
  481.     /* the first data blocks pointers are inside the file header block */
  482.     if (file->nDataBlock<MAX_DATABLK) {
  483.         nSect = adfGet1FreeBlock(file->volume);
  484.         if (nSect==-1) return -1;
  485. //printf("adfCreateNextFileBlock fhdr %ld\n",nSect);
  486.         if (file->nDataBlock==0)
  487.             file->fileHdr->firstData = nSect;
  488.         file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock] = nSect;
  489.         file->fileHdr->highSeq++;
  490.     }
  491.     else {
  492.         /* one more sector is needed for one file extension block */
  493.         if ((file->nDataBlock%MAX_DATABLK)==0) {
  494.             extSect = adfGet1FreeBlock(file->volume);
  495. //printf("extSect=%ld\n",extSect);
  496.             if (extSect==-1) return -1;
  497.  
  498.             /* the future block is the first file extension block */
  499.             if (file->nDataBlock==MAX_DATABLK) {
  500.                 file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
  501.                 if (!file->currentExt) {
  502.                     adfSetBlockFree(file->volume, extSect);
  503.                     (*adfEnv.eFct)("adfCreateNextFileBlock : malloc");
  504.                     return -1;
  505.                 }
  506.                 file->fileHdr->extension = extSect;
  507.             }
  508.  
  509.             /* not the first : save the current one, and link it with the future */
  510.             if (file->nDataBlock>=2*MAX_DATABLK) {
  511.                 file->currentExt->extension = extSect;
  512. //printf ("write ext=%d\n",file->currentExt->headerKey);
  513.                 adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
  514.                     file->currentExt);
  515.             }
  516.  
  517.             /* initializes a file extension block */
  518.             for(i=0; i<MAX_DATABLK; i++)
  519.                 file->currentExt->dataBlocks[i] = 0L;
  520.             file->currentExt->headerKey = extSect;
  521.             file->currentExt->parent = file->fileHdr->headerKey;
  522.             file->currentExt->highSeq = 0L;
  523.             file->currentExt->extension = 0L;
  524.             file->posInExtBlk = 0L;
  525. //printf("extSect=%ld\n",extSect);
  526.         }
  527.         nSect = adfGet1FreeBlock(file->volume);
  528.         if (nSect==-1) 
  529.             return -1;
  530.         
  531. //printf("adfCreateNextFileBlock ext %ld\n",nSect);
  532.  
  533.         file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk] = nSect;
  534.         file->currentExt->highSeq++;
  535.         file->posInExtBlk++;
  536.     }
  537.  
  538.     /* builds OFS header */
  539.     if (isOFS(file->volume->dosType)) {
  540.         /* writes previous data block and link it  */
  541.         if (file->pos>=blockSize) {
  542.             data->nextData = nSect;
  543.             adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
  544. //printf ("writedata=%d\n",file->curDataPtr);
  545.         }
  546.         /* initialize a new data block */
  547.         for(i=0; i<(int)blockSize; i++)
  548.             data->data[i]=0;
  549.         data->seqNum = file->nDataBlock+1;
  550.         data->dataSize = blockSize;
  551.         data->nextData = 0L;
  552.         data->headerKey = file->fileHdr->headerKey;
  553.     }
  554.     else
  555.         if (file->pos>=blockSize) {
  556.             adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
  557. //printf ("writedata=%d\n",file->curDataPtr);
  558.             memset(file->currentData,0,512);
  559.         }
  560.             
  561. //printf("datablk=%d\n",nSect);
  562.     file->curDataPtr = nSect;
  563.     file->nDataBlock++;
  564.  
  565.     return(nSect);
  566. }
  567.  
  568.  
  569. /*
  570.  * adfPos2DataBlock
  571.  *
  572.  */
  573. long adfPos2DataBlock(long pos, int blockSize, 
  574.     int *posInExtBlk, int *posInDataBlk, long *curDataN )
  575. {
  576.     long extBlock;
  577.  
  578.     *posInDataBlk = pos%blockSize;
  579.     *curDataN = pos/blockSize;
  580.     if (*posInDataBlk==0)
  581.         (*curDataN)++;
  582.     if (*curDataN<72) {
  583.         *posInExtBlk = 0;
  584.         return -1;
  585.     }
  586.     else {
  587.         *posInExtBlk = (pos-72*blockSize)%blockSize;
  588.         extBlock = (pos-72*blockSize)/blockSize;
  589.         if (*posInExtBlk==0)
  590.             extBlock++;
  591.         return extBlock;
  592.     }
  593. }
  594.  
  595.  
  596. /*
  597.  * adfReadDataBlock
  598.  *
  599.  */
  600. RETCODE adfReadDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
  601. {
  602.     unsigned char buf[512];
  603.     struct bOFSDataBlock *dBlock;
  604.     RETCODE rc = RC_OK;
  605.  
  606.     adfReadBlock(vol, nSect,buf);
  607.  
  608.     memcpy(data,buf,512);
  609.  
  610.     if (isOFS(vol->dosType)) {
  611. #ifdef LITT_ENDIAN
  612.         swapEndian(data, SWBL_DATA);
  613. #endif
  614.         dBlock = (struct bOFSDataBlock*)data;
  615. //printf("adfReadDataBlock %ld\n",nSect);
  616.  
  617.         if (dBlock->checkSum!=adfNormalSum(buf,20,sizeof(struct bOFSDataBlock)))
  618.             (*adfEnv.wFct)("adfReadDataBlock : invalid checksum");
  619.         if (dBlock->type!=T_DATA)
  620.             (*adfEnv.wFct)("adfReadDataBlock : id T_DATA not found");
  621.         if (dBlock->dataSize<0 || dBlock->dataSize>488)
  622.             (*adfEnv.wFct)("adfReadDataBlock : dataSize incorrect");
  623.         if ( !isSectNumValid(vol,dBlock->headerKey) )
  624.             (*adfEnv.wFct)("adfReadDataBlock : headerKey out of range");
  625.         if ( !isSectNumValid(vol,dBlock->nextData) )
  626.             (*adfEnv.wFct)("adfReadDataBlock : nextData out of range");
  627.     }
  628.  
  629.     return rc;
  630. }
  631.  
  632.  
  633. /*
  634.  * adfWriteDataBlock
  635.  *
  636.  */
  637. RETCODE adfWriteDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
  638. {
  639.     unsigned char buf[512];
  640.     unsigned long newSum;
  641.     struct bOFSDataBlock *dataB;
  642.     RETCODE rc = RC_OK;
  643.  
  644.     newSum = 0L;
  645.     if (isOFS(vol->dosType)) {
  646.         dataB = (struct bOFSDataBlock *)data;
  647.         dataB->type = T_DATA;
  648.         memcpy(buf,dataB,512);
  649. #ifdef LITT_ENDIAN
  650.         swapEndian(buf, SWBL_DATA);
  651. #endif
  652.         newSum = adfNormalSum(buf,20,512);
  653.         swLong(buf+20,newSum);
  654. //        *(long*)(buf+20) = swapLong((unsigned char*)&newSum);
  655.         adfWriteBlock(vol,nSect,buf);
  656.     }
  657.     else {
  658.         adfWriteBlock(vol,nSect,data);
  659.     }
  660. //printf("adfWriteDataBlock %ld\n",nSect);
  661.  
  662.     return rc;
  663. }
  664.  
  665.  
  666. /*
  667.  * adfReadFileExtBlock
  668.  *
  669.  */
  670. RETCODE adfReadFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
  671. {
  672.     unsigned char buf[sizeof(struct bFileExtBlock)];
  673.     RETCODE rc = RC_OK;
  674.  
  675.     adfReadBlock(vol, nSect,buf);
  676. /*printf("read fext=%d\n",nSect);*/
  677.     memcpy(fext,buf,sizeof(struct bFileExtBlock));
  678. #ifdef LITT_ENDIAN
  679.     swapEndian((unsigned char*)fext, SWBL_FEXT);
  680. #endif
  681.     if (fext->checkSum!=adfNormalSum(buf,20,sizeof(struct bFileExtBlock)))
  682.         (*adfEnv.wFct)("adfReadFileExtBlock : invalid checksum");
  683.     if (fext->type!=T_LIST)
  684.         (*adfEnv.wFct)("adfReadFileExtBlock : type T_LIST not found");
  685.     if (fext->secType!=ST_FILE)
  686.         (*adfEnv.wFct)("adfReadFileExtBlock : stype  ST_FILE not found");
  687.     if (fext->headerKey!=nSect)
  688.         (*adfEnv.wFct)("adfReadFileExtBlock : headerKey!=nSect");
  689.     if (fext->highSeq<0 || fext->highSeq>MAX_DATABLK)
  690.         (*adfEnv.wFct)("adfReadFileExtBlock : highSeq out of range");
  691.     if ( !isSectNumValid(vol, fext->parent) )
  692.         (*adfEnv.wFct)("adfReadFileExtBlock : parent out of range");
  693.     if ( !isSectNumValid(vol, fext->extension) )
  694.         (*adfEnv.wFct)("adfReadFileExtBlock : extension out of range");
  695.  
  696.     return rc;
  697. }
  698.  
  699.  
  700. /*
  701.  * adfWriteFileExtBlock
  702.  *
  703.  */
  704. RETCODE adfWriteFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
  705. {
  706.     unsigned char buf[512];
  707.     unsigned long newSum;
  708.     RETCODE rc = RC_OK;
  709.  
  710.     fext->type = T_LIST;
  711.     fext->secType = ST_FILE;
  712.     fext->dataSize = 0L;
  713.     fext->firstData = 0L;
  714.  
  715.     memcpy(buf,fext,512);
  716. #ifdef LITT_ENDIAN
  717.     swapEndian(buf, SWBL_FEXT);
  718. #endif
  719.     newSum = adfNormalSum(buf,20,512);
  720.     swLong(buf+20,newSum);
  721. //    *(long*)(buf+20) = swapLong((unsigned char*)&newSum);
  722.  
  723.     adfWriteBlock(vol,nSect,buf);
  724.  
  725.     return rc;
  726. }
  727. /*###########################################################################*/
  728.